package com.appbee.user.client.presenter;

import java.util.List;

import javax.inject.Inject;
import javax.inject.Provider;

import com.appbee.user.client.AccessControl;
import com.appbee.user.shared.proxy.MemberProxy;
import com.appbee.user.shared.service.MemberServiceRequest;
import com.appbee.user.shared.service.UserRequestFactory;
import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.UIObject;
import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryEditorDriver;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.Request;
import com.google.web.bindery.requestfactory.shared.RequestFactory;

public class UserListActivity extends AbstractActivity
{
	public interface View extends IsWidget
	{

		public void showMembers(List<MemberProxy> response);
		
		public void setPresenter(UserListActivity presenter);
		
	}
	
	public interface EditMemberView extends IsWidget,Editor<MemberProxy>
	{

		public void show(UIObject button);
		
		public void show(int left, int top);
		
		public void setPresenter(UserListActivity presenter);
		
		public RequestFactoryEditorDriver<MemberProxy, ?> createDriver(
				EventBus eventBus, RequestFactory rf);

		public void hide();
		
	}

	private final View view;
	private final Provider<EditMemberView> editViewProvider;
	private EditMemberView editView;
	private final int viewSize = 100;
	private final Receiver<List<MemberProxy>> receiver = new Receiver<List<MemberProxy>>()
	{

		@Override
		public void onSuccess(List<MemberProxy> response)
		{
			view.showMembers(response);
			if(editView!=null)
				editView.hide();
		}
		
	};
	private RequestFactoryEditorDriver<MemberProxy, ?> editorDriver;
	private final UserRequestFactory rf;
	private EventBus eventBus;
	private final AccessControl accessControl;
	
	@Inject
	public UserListActivity(View view,Provider<EditMemberView> editViewProvider,
			UserRequestFactory rf,
			AccessControl accessControl)
	{
		this.rf = rf;
		this.accessControl = accessControl;
		this.view = view;
		this.editViewProvider = editViewProvider;
		this.view.setPresenter(this);
	}
	
	@Override
	public void start(AcceptsOneWidget panel, EventBus eventBus)
	{
		this.eventBus = eventBus;
		panel.setWidget(view);
		rf.getMemberService().findByRange(0, viewSize).fire(receiver);

	}
	
	private EditMemberView getEditMemberView()
	{
		if(editView==null)
		{
			editView = editViewProvider.get();
			editView.setPresenter(this);
		}
		return editView;
	}
	
	public void onNewMember(UIObject button)
	{
		EditMemberView ew = getEditMemberView();
		editorDriver = ew.createDriver(eventBus, rf);
		MemberServiceRequest request = rf.getMemberService();
		MemberProxy member = request.create(MemberProxy.class);
		editorDriver.edit(member, request);
		Request<MemberProxy> saveAndFind = request.save(member);
		saveAndFind.to(new Receiver<MemberProxy>()
		{

			@Override
			public void onSuccess(MemberProxy response)
			{
				if (editView != null)
					editView.hide();
				rf.getMemberService().findByRange(0, viewSize).fire(receiver);
			}

		});
		ew.show(button);
	}

	public void onSave()
	{
		editorDriver.flush().fire();
		
	}

	public boolean isEditMode()
	{
		return accessControl.isMemberOrAdmin();
	}

	public void onDelete(MemberProxy newsProxy)
	{
		Request<List<MemberProxy>> request = rf.getMemberService()
				.removeAndFindByRange(newsProxy, 0, viewSize);
		request.fire(receiver);
		
	}

	public void edit(MemberProxy member,int left, int top)
	{
		getEditMemberView();
		editorDriver = editView.createDriver(eventBus, rf);
		MemberServiceRequest request = rf.getMemberService();
		Request<MemberProxy> saveAndFind = request.save(member);
		saveAndFind.to(new Receiver<MemberProxy>()
		{

			@Override
			public void onSuccess(MemberProxy response)
			{
				if (editView != null)
					editView.hide();
				rf.getMemberService().findByRange(0, viewSize).fire(receiver);
			}

		});
		editorDriver.edit(member, request);
		editView.show(left,top);
	}
	
	

}
